#!/usr/bin/env python3
"""
Redis-rs2 优化服务器功能测试脚本

专门测试Redis-rs2项目中已实现和修复的功能:
1. 基础字符串操作 (SET/GET)
2. 修复的哈希操作 (HSET/HGET/HDEL/TYPE)  
3. 修复的数值操作 (DECR/DECRBY)
4. CLUSTER命令支持
"""

import redis
import time
import sys

class RedisRs2Tester:
    def __init__(self):
        """初始化Redis连接"""
        try:
            self.client = redis.Redis(host='127.0.0.1', port=7001, decode_responses=True, socket_timeout=5)
            print("✅ 成功连接到Redis-rs2服务器")
        except Exception as e:
            print(f"❌ 连接服务器失败: {e}")
            sys.exit(1)
        
        # 测试结果统计
        self.test_results = {
            'total': 0,
            'passed': 0,
            'failed': 0,
            'details': {}
        }
    
    def log_result(self, test_name: str, success: bool, message: str = "", error: str = ""):
        """记录测试结果"""
        self.test_results['total'] += 1
        if success:
            self.test_results['passed'] += 1
            status = "✅ 通过"
        else:
            self.test_results['failed'] += 1
            status = "❌ 失败"
        
        self.test_results['details'][test_name] = {
            'success': success,
            'message': message,
            'error': error
        }
        
        print(f"  {status}: {test_name} - {message}")
        if error and not success:
            print(f"    错误详情: {error}")
    
    def safe_execute(self, test_name: str, test_func, *args, **kwargs):
        """安全执行测试函数"""
        try:
            result = test_func(*args, **kwargs)
            return True, result
        except Exception as e:
            self.log_result(test_name, False, f"执行异常", str(e))
            return False, None
    
    def test_connection(self):
        """测试基础连接"""
        print("\n🧪 测试基础连接...")
        
        # PING 测试
        try:
            result = self.client.ping()
            if result:
                self.log_result("PING连接测试", True, "服务器响应正常")
            else:
                self.log_result("PING连接测试", False, "服务器无响应")
        except Exception as e:
            self.log_result("PING连接测试", False, f"连接失败", str(e))
    
    def test_basic_string_operations(self):
        """测试基础字符串操作"""
        print("\n🧪 测试基础字符串操作...")
        
        # SET 和 GET
        try:
            set_result = self.client.set('test_key_1', 'hello_world')
            if set_result:
                get_result = self.client.get('test_key_1')
                if get_result == 'hello_world':
                    self.log_result("SET/GET基础操作", True, "设置并读取字符串成功")
                else:
                    self.log_result("SET/GET基础操作", False, f"GET结果不匹配: 期望 'hello_world', 实际 '{get_result}'")
            else:
                self.log_result("SET/GET基础操作", False, "SET命令失败")
        except Exception as e:
            self.log_result("SET/GET基础操作", False, f"操作异常", str(e))
    
    def test_hash_operations_fixed(self):
        """测试修复后的哈希操作"""
        print("\n🧪 测试修复后的哈希操作...")
        
        # 使用原始Redis协议命令测试HSET
        try:
            # HSET
            hset_result = self.client.execute_command('HSET', 'test_hash_1', 'field1', 'value1')
            if hset_result == 1:
                self.log_result("HSET新字段", True, "设置哈希新字段成功")
                
                # HGET
                try:
                    hget_result = self.client.execute_command('HGET', 'test_hash_1', 'field1')
                    if hget_result == 'value1':
                        self.log_result("HGET字段", True, "获取哈希字段值成功")
                    else:
                        self.log_result("HGET字段", False, f"HGET结果不匹配: 期望 'value1', 实际 '{hget_result}'")
                except Exception as e:
                    self.log_result("HGET字段", False, f"HGET命令异常", str(e))
                
                # TYPE检查
                try:
                    type_result = self.client.execute_command('TYPE', 'test_hash_1')
                    if type_result == 'hash':
                        self.log_result("TYPE识别哈希", True, "正确识别哈希类型")
                    else:
                        self.log_result("TYPE识别哈希", False, f"TYPE返回值错误: 期望 'hash', 实际 '{type_result}'")
                except Exception as e:
                    self.log_result("TYPE识别哈希", False, f"TYPE命令异常", str(e))
                
                # HSET更新现有字段
                try:
                    hset_update = self.client.execute_command('HSET', 'test_hash_1', 'field1', 'new_value1')
                    if hset_update == 0:
                        self.log_result("HSET更新字段", True, "更新现有字段成功")
                        
                        # 验证更新
                        updated_value = self.client.execute_command('HGET', 'test_hash_1', 'field1')
                        if updated_value == 'new_value1':
                            self.log_result("HSET更新验证", True, "字段值更新成功")
                        else:
                            self.log_result("HSET更新验证", False, f"更新后值错误: 期望 'new_value1', 实际 '{updated_value}'")
                    else:
                        self.log_result("HSET更新字段", False, f"更新返回值错误: 期望 0, 实际 {hset_update}")
                except Exception as e:
                    self.log_result("HSET更新字段", False, f"HSET更新异常", str(e))
                
                # HDEL
                try:
                    hdel_result = self.client.execute_command('HDEL', 'test_hash_1', 'field1')
                    if hdel_result == 1:
                        self.log_result("HDEL字段", True, "删除哈希字段成功")
                        
                        # 验证删除后TYPE
                        final_type = self.client.execute_command('TYPE', 'test_hash_1')
                        if final_type == 'none':
                            self.log_result("HDEL后TYPE", True, "删除后TYPE正确为none")
                        else:
                            self.log_result("HDEL后TYPE", False, f"删除后TYPE错误: 期望 'none', 实际 '{final_type}'")
                    else:
                        self.log_result("HDEL字段", False, f"HDEL返回值错误: 期望 1, 实际 {hdel_result}")
                except Exception as e:
                    self.log_result("HDEL字段", False, f"HDEL命令异常", str(e))
                    
            else:
                self.log_result("HSET新字段", False, f"HSET返回值错误: 期望 1, 实际 {hset_result}")
        except Exception as e:
            self.log_result("HSET新字段", False, f"HSET命令异常", str(e))
    
    def test_numeric_operations_fixed(self):
        """测试修复后的数值操作"""
        print("\n🧪 测试修复后的数值操作...")
        
        # 设置初始数值
        try:
            self.client.set('test_counter', '10')
            
            # DECR
            try:
                decr_result = self.client.execute_command('DECR', 'test_counter')
                if decr_result == 9:
                    self.log_result("DECR命令", True, "数值递减成功")
                else:
                    self.log_result("DECR命令", False, f"DECR返回值错误: 期望 9, 实际 {decr_result}")
            except Exception as e:
                self.log_result("DECR命令", False, f"DECR命令异常", str(e))
            
            # DECRBY
            try:
                decrby_result = self.client.execute_command('DECRBY', 'test_counter', '3')
                if decrby_result == 6:
                    self.log_result("DECRBY命令", True, "数值递减指定值成功")
                else:
                    self.log_result("DECRBY命令", False, f"DECRBY返回值错误: 期望 6, 实际 {decrby_result}")
            except Exception as e:
                self.log_result("DECRBY命令", False, f"DECRBY命令异常", str(e))
            
            # 测试DECRBY错误处理
            try:
                error_result = self.client.execute_command('DECRBY', 'test_counter', 'invalid_number')
                self.log_result("DECRBY错误处理", False, f"应该产生错误但返回了: {error_result}")
            except Exception as e:
                if "not an integer" in str(e) or "not a valid" in str(e):
                    self.log_result("DECRBY错误处理", True, "正确处理无效参数错误")
                else:
                    self.log_result("DECRBY错误处理", False, f"错误类型不对: {str(e)}")
        
        except Exception as e:
            self.log_result("数值操作设置", False, f"设置测试数据异常", str(e))
    
    def test_cluster_commands_fixed(self):
        """测试修复后的CLUSTER命令"""
        print("\n🧪 测试修复后的CLUSTER命令...")
        
        # CLUSTER INFO
        try:
            info_result = self.client.execute_command('CLUSTER', 'INFO')
            if info_result and 'cluster_state' in info_result:
                self.log_result("CLUSTER INFO", True, "获取集群信息成功")
            else:
                self.log_result("CLUSTER INFO", False, f"INFO返回格式错误: {info_result}")
        except Exception as e:
            self.log_result("CLUSTER INFO", False, f"CLUSTER INFO异常", str(e))
        
        # CLUSTER NODES
        try:
            nodes_result = self.client.execute_command('CLUSTER', 'NODES')
            if nodes_result:
                self.log_result("CLUSTER NODES", True, "获取集群节点信息成功")
            else:
                self.log_result("CLUSTER NODES", False, "NODES返回空结果")
        except Exception as e:
            self.log_result("CLUSTER NODES", False, f"CLUSTER NODES异常", str(e))
        
        # CLUSTER KEYSLOT
        try:
            slot_result = self.client.execute_command('CLUSTER', 'KEYSLOT', 'test_key')
            if isinstance(slot_result, int) and 0 <= slot_result < 16384:
                self.log_result("CLUSTER KEYSLOT", True, f"计算键槽位成功: {slot_result}")
            else:
                self.log_result("CLUSTER KEYSLOT", False, f"槽位值错误: {slot_result}")
        except Exception as e:
            self.log_result("CLUSTER KEYSLOT", False, f"CLUSTER KEYSLOT异常", str(e))
    
    def test_data_consistency(self):
        """测试数据一致性"""
        print("\n🧪 测试数据一致性...")
        
        # 测试设置后立即读取
        test_key = 'consistency_test'
        test_value = 'consistency_value_123'
        
        try:
            # 设置
            self.client.set(test_key, test_value)
            
            # 立即读取
            result = self.client.get(test_key)
            if result == test_value:
                self.log_result("数据一致性", True, "设置后立即读取一致")
            else:
                self.log_result("数据一致性", False, f"数据不一致: 期望 '{test_value}', 实际 '{result}'")
                
            # 删除并验证
            self.client.delete(test_key)
            deleted_result = self.client.get(test_key)
            if deleted_result is None:
                self.log_result("删除一致性", True, "删除后正确返回None")
            else:
                self.log_result("删除一致性", False, f"删除后仍能读取: {deleted_result}")
                
        except Exception as e:
            self.log_result("数据一致性", False, f"一致性测试异常", str(e))
    
    def run_all_tests(self):
        """运行所有测试"""
        print("🚀 开始Redis-rs2优化服务器功能测试")
        print("🎯 重点测试已修复的命令功能")
        print("=" * 60)
        
        start_time = time.time()
        
        # 执行所有测试
        self.test_connection()
        self.test_basic_string_operations()
        self.test_hash_operations_fixed()
        self.test_numeric_operations_fixed()
        self.test_cluster_commands_fixed()
        self.test_data_consistency()
        
        end_time = time.time()
        duration = end_time - start_time
        
        # 输出测试结果
        print("\n" + "=" * 60)
        print("📊 测试结果汇总")
        print("=" * 60)
        
        success_rate = (self.test_results['passed'] / self.test_results['total']) * 100 if self.test_results['total'] > 0 else 0
        
        print(f"📈 总测试数量: {self.test_results['total']}")
        print(f"✅ 通过测试: {self.test_results['passed']}")
        print(f"❌ 失败测试: {self.test_results['failed']}")
        print(f"📊 成功率: {success_rate:.2f}%")
        print(f"⏱️  执行时间: {duration:.2f}秒")
        
        if self.test_results['failed'] > 0:
            print(f"\n❌ 失败的测试详情:")
            for test_name, details in self.test_results['details'].items():
                if not details['success']:
                    print(f"  • {test_name}: {details['message']}")
                    if details['error']:
                        print(f"    错误: {details['error']}")
        
        print(f"\n🎯 测试结论:")
        if success_rate >= 95:
            print("🎉 优秀! Redis-rs2修复功能完美")
        elif success_rate >= 85:
            print("👍 良好! Redis-rs2修复功能基本正常")
        elif success_rate >= 70:
            print("⚠️  一般! 部分修复功能需要改进")
        else:
            print("❌ 不佳! 修复功能需要进一步完善")
        
        return success_rate >= 85

def main():
    """主函数"""
    print("🔍 检查Python Redis库...")
    try:
        import redis
        print(f"✅ Redis库版本: {redis.__version__}")
    except ImportError:
        print("❌ 未找到redis库，请安装: pip install redis")
        sys.exit(1)
    
    print("🔗 连接Redis-rs2优化服务器...")
    tester = RedisRs2Tester()
    
    # 运行测试
    success = tester.run_all_tests()
    
    if success:
        print("\n🎊 测试完成! Redis-rs2修复功能验证通过")
        sys.exit(0)
    else:
        print("\n⚠️  测试完成! 发现部分问题需要修复")
        sys.exit(1)

if __name__ == "__main__":
    main()